package com.ebrothers.isns;

import java.util.HashMap;
import java.util.Map.Entry;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.ebrothers.isns.common.Constants;
import com.ebrothers.isns.controller.ViewController;
import com.ebrothers.isns.controller.ViewControllerFactory;
import com.ebrothers.isns.view.ViewStack;

public final class NavigationManager {
	private static final String TAG = "NavigationManager";
	private static final NavigationManager SINGLETON = new NavigationManager();

	public synchronized static NavigationManager getInstance() {
		return SINGLETON;
	}

	private Context mContext;
	private ViewStack mViewStack;
	private HashMap<NavigatedView, ViewController> mControllers;
	private NavigatedView mCurrentView = NavigatedView.VIEW_QS;
	private OnNavigationListener mListener;

	private NavigationManager() {
		mControllers = new HashMap<NavigatedView, ViewController>();
	}

	public void represent(Context context, ViewStack viewStack) {
		if (Constants.LOGD) {
			Log.d(TAG, "****** represent. ");
		}
		mContext = context;
		mViewStack = viewStack;
		View currChild = mViewStack.getChildAt(NavigatedView.VIEW_QS.ordinal());
		ViewController controller = ViewControllerFactory.createController(
				mContext, NavigatedView.VIEW_QS, currChild);
		mControllers.put(NavigatedView.VIEW_QS, controller);
		controller.onViewBinded(currChild);

		currChild = mViewStack.getChildAt(NavigatedView.VIEW_AS.ordinal());
		controller = ViewControllerFactory.createController(mContext,
				NavigatedView.VIEW_AS, currChild);
		mControllers.put(NavigatedView.VIEW_AS, controller);
		controller.onViewBinded(currChild);

		currChild = mViewStack.getChildAt(NavigatedView.VIEW_MAP.ordinal());
		controller = ViewControllerFactory.createController(mContext,
				NavigatedView.VIEW_MAP, currChild);
		mControllers.put(NavigatedView.VIEW_MAP, controller);
		controller.onViewBinded(currChild);
	}

	public void navigateTo(NavigatedView view, Bundle data, boolean track) {
		if (Constants.LOGD) {
			Log.d(TAG, "****** navigateTo. view=" + view + ", data=" + data
					+ ", mControllers=" + mControllers);
		}
		mCurrentView = view;
		ViewController controller = mControllers.get(view);
		if (data != null) {
			controller.setData(data);
		}
		controller.onViewSelected(data);
		for (Entry<NavigatedView, ViewController> entry : mControllers
				.entrySet()) {
			if (!entry.getKey().equals(view)) {
				entry.getValue().onViewUnselected();
			}
		}
		if (mViewStack.getDisplayedChild() != view.ordinal() && track) {
			mViewStack.trackCurrentView();
		}
		mViewStack.setDisplayedChild(view.ordinal());
		if (mListener != null) {
			mListener.onNavigation(view);
		}
	}

	public boolean isNavigatedView(NavigatedView view) {
		return mCurrentView.equals(view);
	}

	public ViewController getCurrentController() {
		if (Constants.LOGD) {
			Log.d(TAG, "****** getCurrentController. mCurrentView="
					+ mCurrentView + ", mControllers=" + mControllers);
		}
		return mControllers.get(mCurrentView);
	}

	public void setOnNavigationListener(OnNavigationListener listener) {
		mListener = listener;
	}

	public interface OnNavigationListener {
		public void onNavigation(NavigatedView view);
	}

	public static enum NavigatedView {
		VIEW_QS, VIEW_AS, VIEW_MAP;
		public static NavigatedView getNavigatedView(int i) {
			switch (i) {
			case 0:
				return VIEW_QS;
			case 1:
				return VIEW_AS;
			case 2:
				return VIEW_MAP;
			default:
				break;
			}
			return null;
		}
	}
}
